﻿using Dapper;
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CK.Sprite.Framework;

namespace CK.Sprite.JobCore
{
    public class JobConfigRepository : GuidRepositoryBase<JobConfig>, IJobConfigRepository
    {
        public JobConfigRepository(IUnitOfWork unitOfWork) : base(unitOfWork) { }

        public async Task<List<JobConfig>> GetActiveJobConfigs()
        {
            string strSql = "SELECT * FROM JobConfigs WHERE IsActive=1;";
            var result = await _unitOfWork.Connection.QueryAsync<JobConfig>(strSql, transaction: _unitOfWork.Transaction);
            return result.ToList();
        }

        public async Task<PageResultDto<JobConfig>> GetJobConfigs(GetJobConfigsInput configsInput)
        {
            var result = new PageResultDto<JobConfig>();

            var strSql = $"SELECT * FROM JobConfigs#where# LIMIT {configsInput.SkipCount},{configsInput.MaxResultCount};";
            var strCountSql = "SELECT COUNT(1) FROM JobConfigs#where#;";

            var strWhere = " WHERE 1=1";
            if (!string.IsNullOrEmpty(configsInput.Filter))
            {
                strWhere += $" AND (JobName LIKE '%{configsInput.Filter}%' OR Params LIKE '%{configsInput.Filter}%' OR Description LIKE '%{configsInput.Filter}%' OR ExecLocation LIKE '%{configsInput.Filter}%' OR JobGroup LIKE '%{configsInput.Filter}%')";
            }
            if (configsInput.TriggerType.HasValue)
            {
                strWhere += $" AND TriggerType='{(int)configsInput.TriggerType}'";
            }
            if (configsInput.JobExecType.HasValue)
            {
                strWhere += $" AND JobExecType='{(int)configsInput.JobExecType}'";
            }
            if (configsInput.IsActive.HasValue)
            {
                strWhere += $" AND IsActive='{(configsInput.IsActive.Value ? "1" : "0")}'";
            }

            result.Items = (await _unitOfWork.Connection.QueryAsync<JobConfig>(strSql.Replace("#where#", strWhere), transaction: _unitOfWork.Transaction)).ToList();
            result.TotalCount = await _unitOfWork.Connection.QueryFirstOrDefaultAsync<long>(strCountSql.Replace("#where#", strWhere), transaction: _unitOfWork.Transaction);

            return result;
        }

        public async Task<PageResultDto<JobExecLog>> GetJobExecLogs(GetJobExecLogsInput execLogsInput)
        {
            var result = new PageResultDto<JobExecLog>();

            var strSql = $"SELECT * FROM JobExecLogs#where# LIMIT {execLogsInput.SkipCount},{execLogsInput.MaxResultCount};";
            var strCountSql = "SELECT COUNT(1) FROM JobExecLogs#where#;";

            var strWhere = " WHERE 1=1";
            if (!string.IsNullOrEmpty(execLogsInput.Filter))
            {
                strWhere += $" AND (JobName LIKE '%{execLogsInput.Filter}%' OR Params LIKE '%{execLogsInput.Filter}%' OR Description LIKE '%{execLogsInput.Filter}%' OR ExecLocation LIKE '%{execLogsInput.Filter}%' OR JobGroup LIKE '%{execLogsInput.Filter}%')";
            }
            if (execLogsInput.TriggerType.HasValue)
            {
                strWhere += $" AND TriggerType='{(int)execLogsInput.TriggerType}'";
            }
            if (execLogsInput.JobExecType.HasValue)
            {
                strWhere += $" AND JobExecType='{(int)execLogsInput.JobExecType}'";
            }
            if (execLogsInput.ExecType.HasValue)
            {
                strWhere += $" AND ExecType='{(int)execLogsInput.ExecType}'";
            }

            DateTime startTime = execLogsInput.StartTime.HasValue ? execLogsInput.StartTime.Value.Date : DateTime.MinValue;
            DateTime endTime = execLogsInput.EndTime.HasValue ? execLogsInput.EndTime.Value.Date.AddDays(1).AddMilliseconds(-1) : DateTime.MaxValue;
            strWhere += $" AND ExecStartTime BETWEEN '{startTime.ToString("yyyy-MM-dd HH:mm:ss")}' AND '{endTime.ToString("yyyy-MM-dd HH:mm:ss")}'";

            result.Items = (await _unitOfWork.Connection.QueryAsync<JobExecLog>(strSql.Replace("#where#", strWhere), transaction: _unitOfWork.Transaction)).ToList();
            result.TotalCount = await _unitOfWork.Connection.QueryFirstOrDefaultAsync<long>(strCountSql.Replace("#where#", strWhere), transaction: _unitOfWork.Transaction);

            return result;
        }
    }
}
